#include "stdafx.h"
#include "parameter_editor.h"

Editor::Editor(QWidget* pwgt) 
	: QDialog(pwgt, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{
	ui.setupUi(this);
	connect(ui.btnAccept, SIGNAL(clicked), this, SLOT(on_btnAccept_clicked));
	connect(ui.btnReject, SIGNAL(clicked), this, SLOT(on_btnReject_clicked));
	connect(ui.btnLoad, SIGNAL(clicked), this, SLOT(on_btnLoad_clicked));
	connect(ui.btnAddRow, SIGNAL(clicked), this, SLOT(on_btnAddRow_clicked));
	connect(ui.btnRemoveRow, SIGNAL(clicked), this, SLOT(on_btnRemoveRow_clicked));
	connect(ui.btnRefresh, SIGNAL(clicked), this, SLOT(on_btnRefresh_clicked));
	connect(ui.bClear, SIGNAL(clicked), this, SLOT(on_bClear_clicked));
	//connect(ui.cmType, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(update_plot_sl(const QString&)));
	connect(ui.cmType, SIGNAL(currentIndexChanged(int)), this, SLOT(update_plot_sl(int)));
	ui.table->setStyleSheet("alternate-background-color: rgb(190, 234, 235)");
	ui.table->setItemDelegate(new LineEditDelegate);
	ui.loPlot->setSizeConstraint(QLayout::SetMaximumSize);
	plot = new QCustomPlot();
	plot->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	plot->addGraph();
	update();
	ui.loPlot->addWidget(plot);
}

Editor::~Editor(){
	delete plot;
}

void Editor::on_btnAccept_clicked(){
	accept();
}

void Editor::on_btnReject_clicked(){
	int result = QMessageBox::information(this, "Close", 
		"Close the form? any unsaved data will be lost", 
		QMessageBox::Yes | QMessageBox::Default, 
		QMessageBox::No, 
		QMessageBox::Cancel | QMessageBox::Escape); 
	if (result == QMessageBox::Yes) 
		reject();
}

void Editor::on_bClear_clicked(){
	int result = QMessageBox::information(this, "Clear", 
		"Clear data?", 
		QMessageBox::Yes | QMessageBox::Default, 
		QMessageBox::No, 
		QMessageBox::Cancel | QMessageBox::Escape); 
	if (result == QMessageBox::Yes) {
		ui.table->setRowCount(1);
		x.resize(1);
		x.resize(1);
		x[0] = new QTableWidgetItem();
		ui.table->setItem(1, 0, x[0]);
	}
}

void Editor::on_btnRefresh_clicked(){
	update_plot();
}

void Editor::on_btnAddRow_clicked(){
	int i = ui.table->currentRow() + 1;
	if (!i) i = 1;
	ui.table->insertRow(i);
	x.insert(x.begin()+ i,new QTableWidgetItem);
	ui.table->setItem(i, 0, x[i]);
	y.insert(y.begin()+ i,new QTableWidgetItem);
	ui.table->setItem(i, 1, y[i]);
}

void Editor::on_btnRemoveRow_clicked(){
	int i = ui.table->currentRow();
	if (i < 1) return;
	ui.table->removeRow(i);
	x.erase(x.begin()+ i);
	y.erase(y.begin()+ i);
}

void Editor::on_btnLoad_clicked(){
	vector<double> dbl_x, dbl_y;
	QString FileLoading = QFileDialog::getOpenFileName(this,"Open","c:/","File CSV(*.csv)");
	QFile file(FileLoading);
	if(file.open(QIODevice::ReadOnly)){
		QTextStream stream(&file);
		QString str = stream.readAll();
		QStringList list = str.split('\n');

		for (unsigned int i = 0; i < list.size(); i++)
			if (list[i].size()){
				QStringList row = list[i].split(";");
				for (unsigned int j = 0; j < row.size(); j++)
					if(row[j].toStdString() == "\r") row.removeAt(j);
				if (row.size() == 2){
					dbl_x.push_back(row[0].toDouble());
					dbl_y.push_back(row[1].toDouble());
				}else{
					QMessageBox::critical(this, "Error", "Error on line " + QString("%1").arg(i + 1), QMessageBox::Ok);	
					dbl_x.clear();
					break;
				}
			}
		ui.table->setRowCount(dbl_x.size());
		x.resize(dbl_x.size());
		y.resize(dbl_y.size());
		for(int i = 0; i < x.size(); i++){
			x[i] = new QTableWidgetItem;
			x[i]->setData(Qt::EditRole, QString::number(dbl_x[i]));
			ui.table->setItem(i, 0, x[i]);
			y[i] = new QTableWidgetItem;
			y[i]->setData(Qt::EditRole, QString::number(dbl_y[i]));
			ui.table->setItem(i, 1, y[i]);
		}
	}
	checkFirstRow();
	update_plot();
}

void Editor::checkFirstRow(){
	if (!x.size()){
		ui.table->setRowCount(1);
		x.resize(1);
		y.resize(1);
		x[0] = new QTableWidgetItem;
		ui.table->setItem(0, 0, x[0]);
		y[0] = new QTableWidgetItem;
		ui.table->setItem(0, 1, y[0]);
	}
	x[0]->setData(Qt::EditRole, 0);
	x[0]->setBackgroundColor(QColor(230, 230, 230));
	x[0]->setFlags(Qt::ItemIsSelectable);
}

void Editor::setData(const QString &name, const QString &text){
	ui.lblParameterName->setText(name);
	QStringList list = text.split("//");
	QString type = list[0];
	QStringList title = list[1].split(":");
	QStringList unit = list[2].split(":");
	QStringList data = list[3].split(";");
	QStringList x_unit = g_units.getUnitList(unit.front());
	QStringList y_unit = g_units.getUnitList(unit.back());
	int index = 0;
	for(int i = 0; i < x_unit.count(); i++){
		ui.cmXUnit->addItem(x_unit[i]);
		if (unit.front() == x_unit[i]) index = i;
	}
	ui.cmXUnit->setCurrentIndex(index);
	index = 0;
	for(int i = 0; i < y_unit.count(); i++){
		ui.cmYUnit->addItem(y_unit[i]);
		if (unit.back() == y_unit[i]) index = i;
	}
	ui.cmYUnit->setCurrentIndex(index);

	ui.table->horizontalHeaderItem(0)->setText(title[0]);
	ui.table->horizontalHeaderItem(1)->setText(title[1]);
	plot->xAxis->setLabel(title[0]);
	plot->yAxis->setLabel(title[1]);
	ui.table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);  
	ui.table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);  
	int data_count = data.count();
	if (data.count() == 1 && data[0] == "") data_count = 0;
	ui.table->setRowCount(data_count);
	x.resize(data_count);
	y.resize(data_count);
	for(int i = 0; i < data_count; i++){

		x[i] = new QTableWidgetItem;
		x[i]->setData(Qt::EditRole, data[i].split(":")[0]);
		ui.table->setItem(i, 0, x[i]);
		y[i] = new QTableWidgetItem;
		y[i]->setData(Qt::EditRole, data[i].split(":")[1]);
		ui.table->setItem(i, 1, y[i]);
	}
	if(type.split(":").count() == 2){
		ui.cmType->addItem("piecewise-linear");
		ui.cmType->addItem("piecewise-constant");
		if(type.split(":")[1] == "piecewise-linear") ui.cmType->setCurrentIndex(0);
		else ui.cmType->setCurrentIndex(1);
	}else{
		 ui.cmType->addItem(type);
		 ui.cmType->setVisible(false);
		 ui.lblType->setVisible(false);
		 ui.loBnt->removeItem(ui.hsType);
	}
	checkFirstRow();
	update_plot();
}

QString Editor::getData(){
	QString type;
	if(ui.cmType->count() == 2) type = "both:";
	type += ui.cmType->currentText();
	QString title = ui.table->horizontalHeaderItem(0)->text() + ":" + ui.table->horizontalHeaderItem(1)->text();
	QString unit = ui.cmXUnit->currentText() + ":" + ui.cmYUnit->currentText();
	QString data = "";
	vector<double> dbl_x, dbl_y;
	for (int i = 0; i < ui.table->rowCount(); i++){
		QString str_x, str_y;
		str_x = x[i]->data(0).toString();
		str_y = y[i]->data(0).toString();
		if (str_x != "" && str_y != ""){
			dbl_x.push_back(x[i]->data(0).toDouble());
			dbl_y.push_back(y[i]->data(0).toDouble());
		}
	}
	//sort
	int step = dbl_x.size() / 2;
	while (step > 0){
		for (int i = 0; i < (dbl_x.size() - step); i++){
			int j = i;
			while (j >= 0 && dbl_x[j] > dbl_x[j + step]){
				int temp = dbl_x[j];
				dbl_x[j] = dbl_x[j + step];
				dbl_x[j + step] = temp;
				temp = dbl_y[j];
				dbl_y[j] = dbl_y[j + step];
				dbl_y[j + step] = temp;
				j--; 
			}
		}
		step = step / 2;
	}    
	for(unsigned int i = 0; i < dbl_x.size(); i++){
		if (data != "") data += ";";
		data += QString::number(dbl_x[i]) + ":" +  QString::number(dbl_y[i]);
	}
	return type + "//" + title + "//" + unit + "//" + data;
}

void Editor::update_plot(){
	QVector<double> _x, _y;
	bool type_is_const = ui.cmType->currentIndex() == 1;
	for (int i = 0; i < ui.table->rowCount(); i++){
		_x.push_back(x[i]->data(0).toDouble());
		_y.push_back(y[i]->data(0).toDouble());
/*
		if (type_is_const){
			_x.push_back(_x.back());
			_y.push_back(_y.back());
		}
		plot->set*/
	}
	if (type_is_const) plot->graph(0)->setLineStyle(QCPGraph::lsStepLeft);
	else plot->graph(0)->setLineStyle(QCPGraph::lsLine);
	plot->graph(0)->setData(_x, _y);
	plot->graph(0)->setPen(QPen(Qt::blue, 3));
	
	plot->graph(0)->rescaleAxes();
	plot->replot();
}


LineEditDelegate::LineEditDelegate(QObject* parent)
	: QItemDelegate(parent){
}

QWidget* LineEditDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& /*option*/, const QModelIndex& index ) const
{
	Q_UNUSED(index);
	QLineEdit* lineEdit = new QLineEdit(parent);
	lineEdit->setValidator(new QIntValidator(-1e10,1e10,lineEdit));
	return lineEdit;
}

void LineEditDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
	QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor);
	if (!lineEdit) return;

	lineEdit->setText(index.data(Qt::EditRole).toString());
}

void LineEditDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
	QLineEdit* lineEdit(qobject_cast<QLineEdit*>(editor));
	if (!lineEdit) return;
	model->setData(index, lineEdit->text());
}

void LineEditDelegate::updateEditorGeometry(QWidget* editor,
	const QStyleOptionViewItem& option, const QModelIndex& /* index */) const
{
	editor->setGeometry(option.rect);
}